/*
    封装一个SqliteDB类，提供简单的数据库操作接口，能够支持数据库的增删改查操作
    1. 创建数据库文件
    2. 执行sql语句
    3. 关闭数据库文件
*/
#pragma once
#include <iostream>
#include <string>
#include "sqlite3.h"

class SqliteDB
{
public:
    /*
        对于查询结果的每一行都会调用一次这个回调函数
        data: 调用回调函数时传入的参数
        col_count: 一行数据的列数
        result: 一行数据的字符指针数组
        fields_name: 一行字段名的字符指针数组
    */
    // 执行sql时的回调函数类型
    typedef int(*SqlCallback)(void* data, int col_count, char** result, char** fields_name);

public:
    SqliteDB(const std::string& db_file) : _db_file(db_file)
    {
    }

    // 打开数据库文件
    bool open(int THREAD_SAFE_MODE = SQLITE_OPEN_FULLMUTEX)
    {
        int ret = sqlite3_open_v2(_db_file.c_str(), &_db_handler, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |  THREAD_SAFE_MODE, NULL);
        if(ret != SQLITE_OK)
        {
            std::cout << "open/create db failed" << sqlite3_errmsg(_db_handler) << std::endl;
            return false;
        }
        return true;
    }

    // 执行sql语句
    bool execute(const std::string& sql, SqlCallback callback, void* arg)
    {
        int ret = sqlite3_exec(_db_handler, sql.c_str(), callback, arg, NULL);
        if(ret != SQLITE_OK)
        {
            std::cout << "'" << sql << "'" << " execute failed: " << sqlite3_errmsg(_db_handler) << std::endl;
            return false;
        }
        return true;
    }

    // 关闭数据库文件
    void close()
    {
        if(_db_handler)
            sqlite3_close_v2(_db_handler);
    }

private:
    sqlite3 *_db_handler;
    std::string _db_file;
};